/* 
 * File:   Rect.h
 * Author: RedEyedKiller
 *
 * Created on 23 Μάρτιος 2010, 1:30 πμ
 */

#ifndef _RECT_H
#define	_RECT_H

//              Rect coordinates
//   (top,left)-------------------(top,left+width)
//    |                                 |
//    |                                 |
//    |                                 |
//    |                                 |
//   (top+height,left)------------(top+height,left+width)
//

#include "Shape.h"
#include "Vector2.h"

namespace Math
{
/* class pre - def*/
class Circle;

class Rect : public Shape
{
public:
    // <editor-fold defaultstate="collapsed" desc="Constructors">

    Rect()
    {
		top = 0;
		left = 0;
		height = 0;
		width = 0;
    }
    ~Rect()
    {
    }
    Rect(int top, int left, int height, int width);
    Rect(float top, float left, float height, float width);
    Rect(double top, double left, double height, double width);
    Rect(const Rect& orig);
    Rect & operator=(const Rect& orig);
    virtual Shape* Clone();// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Setys & Getys">

    void Set(int top, int left, int height, int width);
    void Set(float top, float left, float height, float width);
    void Set(double top, double left, double height, double width);

    inline void SetLeft(int left)
    {
        this->left = left;
    }

    inline int GetLeft() const
    {
        return left;
    }

    inline void SetTop(int top)
    {
        this->top = top;
    }

    inline int GetTop() const
    {
        return top;
    }

    inline void SetWidth(int width)
    {
        this->width = width;
    }

    inline int GetWidth() const
    {
        return width;
    }

    inline void SetHeight(int height)
    {
        this->height = height;
    }

    inline int GetHeight() const
    {
        return height;
    }

    inline int GetTotalHeight() const
    {
        return top + height;
    }

    inline int GetTotalWidth() const
    {
        return left + width;
    }// </editor-fold>

    /**
     * returns the center of the rect
     */
    virtual Vector2F GetCenter() const;
    
    /**
     * Sets the center of the rect.
     * @param center
     */
    virtual void SetCenter(const Vector2F& center);
    
    /**
     * @return The origin vector (left,top).
     */
    Vector2I GetOrigin() const;
    
    /**
     * @return the vector (width,height)
     */
    Vector2F GetDimensions();
    
    /**
     * Set the left and top of the rect.
     * @param origin top = origin.y left = origin.x
     */
    void SetOrigin(const Vector2I& origin);
    void SetOrigin(int x,int y);
    
    /**
     * Adds to the top and left of the rect the x y of the specified vector.
     * @param origin
     */
    void MoveOrigin(const Vector2I& origin);
    void MoveOrigin(int x,int y);
    
    /**
     *  Methods which return the distance between this and other shapes
     */
    virtual Vector2Templ<float> DistanceClosestPoint(const Shape& shape) const;
    virtual Vector2Templ<float> DistanceClosestPoint(const Vector2F& vect) const;
    
    /**
     * return true if this intersects with rect
     */
    virtual bool Intersect(const Shape& shape) const;
    virtual bool Intersect(const Vector2I& vec) const;
    virtual bool Intersect(const Vector2F& vec) const;
    
    /*the extented Intersection method proxies*/
    /*for more info look @ Math.h */
    virtual IntersectionType Intersect(const Shape& shape, Vector2Templ<float>& axisInfo)  const;
    /*returns the total area tha this rect holds*/
    virtual float CalculateArea() const;
protected:
    //protected methods used for double dispatching
    //look at Shape.h for more info
    virtual bool IntersectWith(const Circle& circle) const;
    virtual bool IntersectWith(const Rect& rect) const;
    virtual IntersectionType IntersectWith(const Circle& circle, Vector2Templ<float>& axisInfo) const;
    virtual IntersectionType IntersectWith(const Rect& rect, Vector2Templ<float>& axisInfo) const;
    virtual Vector2Templ<float> DistanceClosestPointFrom(const Rect& rect) const;
    virtual Vector2Templ<float> DistanceClosestPointFrom(const Circle& circle) const;
private:
    int height;
    int width;
    int top; //the y element of the uper left point of the rect
    int left; //the x element of the uper left point of the rect
};
};
#endif	/* _RECT_H */
